<template>
  <input type="text" ref="inputRef" :value="modelValue" @input="handleInput" @change="handleChange"
    @blur="handleBlur" />
  <span v-if="errorMessage" class="error-msg">{{ errorMessage }}</span>
</template>

<script setup lang="ts">
import { onMounted, inject, ref, watch } from "vue";
import type { RuleItem } from './BaseForm.vue';
// 定义子组件暴露给Form的类型
interface InputComponent {
  validate: (trigger: string) => boolean;
}
// 在input 组件里面定义 属性
const props = defineProps<{
  rules?: RuleItem[]; // 组件可以自己指定规则，也可以从表单继承
  name: string; // v-model绑定值
  modelValue: string; // 输入框名称，用于关联规则
  placeholder: string; // 输入框占位符
}>();
// 定义事件
const emit = defineEmits<{
  'update:modelValue': [value: string];
}>();
// 从父级Form组件注入上下文
const formContext = inject<{
  registerInput: (name: string, component: InputComponent) => void;
  handleValidation: (name: string, isVaild: boolean, errorMsg: string) => void;
  rules: RuleItem[];
}>('formContext');
const inputRef = ref<HTMLInputElement | null>(null);
const errorMessage = ref('');
// 获取有效的规则列表（组件自身规则优先，否则使用表单规则）
const getEffectiveRules = () => {
  if (props.rules && props.rules.length > 0) {
    return props.rules;
  }
  return formContext?.rules.filter(rule => rule.name === props.name) || [];
}
// 校验函数
const validate = (trigger: string): boolean => {
  const rules = getEffectiveRules();
  if (rules.length === 0) return true;
  // 查找匹配当前触发条件的规则
  const matchedRules = rules.filter(rule => rule.trigger === trigger);
  // 遍历规则进行检验
  for (const rule of matchedRules) {
    const value = props.modelValue;

    // 进行校验
    if (rule.type === 'Required' && !value.trim()) {
      errorMessage.value = rule.errorMsg;
      formContext?.handleValidation(props.name, false, rule.errorMsg);
      return false;
    }
    if (rule.type === 'Numbric' && value && !/^\d+$/.test(value)) {
      errorMessage.value = rule.errorMsg;
      formContext?.handleValidation(props.name, false, rule.errorMsg);
      return false;
    }
  }
  // 校验通过
  errorMessage.value = '';
  formContext?.handleValidation(props.name, true, '');
  return true;
}
// 事件处理函数
const handleInput = (event: Event) => {
  const value = (event.target as HTMLInputElement).value;
  emit('update:modelValue', value);
  validate('Input');
};
const handleChange = () => {
  validate('Change');
};
const handleBlur = () => {
  validate('Blur');
}
// 监听modelValue变化，当值被外部修改时重新校验
watch(() => props.modelValue, () => {
  // 当值被清空时，清除错误信息
  if (!props.modelValue.trim()) {
    errorMessage.value = '';
    formContext?.handleValidation(props.name, true, '');
  }
});
// 暴露validate方法给父组件调用
defineExpose({
  validate
})
onMounted(() => {
  // 在挂载时向表单注册自身
  if (formContext) {
    formContext.registerInput(props.name, {
      validate
    })
  }
});
</script>

<style scoped lang="scss">
.error-msg {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  padding-top: 4px;
  margin-left: 8px;
}

input {
  padding: 4px 8px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  outline: none;
  transition: border-color 0.2s;
}

input:focus {
  border-color: #409eff;
}
</style>
